﻿using System;
using Furiant.Figment.Core;

namespace Furiant.Figment.Items.Lootable
{
    public static class LootableExtensions
    {
        /// <summary>
        /// Subtracts units from the source instance and adds them to the target. 
        /// Number of units traded depends on the UnitCount of the instance, and the difference of UnitsPerGroup and UnitCount of the target.
        /// </summary>
        /// <typeparam name="T">ILootable</typeparam>
        /// <param name="source">The item whose units will be transferred to the target.</param>
        /// <param name="target">The item which will receive the units from the source.</param>
        /// <param name="amount">The number of units to transfer. </param>
        public static void TransferUnits<T>(this T source, T target, int amount) where T : ILootable
        {
            if (source.UnitCount <= 1 || amount <= 1) return;

            var targetCapacity = target.UnitsPerGroup - target.UnitCount;
            if (targetCapacity < 1) return;

            var actualAmount = Math.Min(source.UnitCount, amount);

            var difference = Math.Min(targetCapacity, actualAmount);

            source.UnitCount -= difference;
            target.UnitCount += difference;
        }

        /// <summary>
        /// Subtracts the specified number of units from the instance and returns a clone with a UnitCount of that amount.
        /// </summary>
        /// <typeparam name="T">ILootable</typeparam>
        /// <param name="source">The item whose units will be subtracted.</param>
        /// <param name="take">The quantity of units to take from the source.</param>
        /// <returns></returns>
        public static T Split<T>(this T source, ushort take) where T : ILootable
        {
            if (take < 1) throw new ArgumentOutOfRangeException("take", "Amount to take must be greater than zero.");
            if (source.UnitCount <= 1) throw new ArgumentException("Not enough units to split.", "source");

            var clone = source.GetClone<T>();
            clone.UnitCount = Utility.ClampNumber(1, source.UnitCount - 1, take);
            source.UnitCount -= take;
            
            return clone;
        }
    }
}
